/** swi_asm.S: SWI handler
 *
 * Author: 	Nora Tarano <ntarano@andrew.cmu.edu>
 *          Yuan Meng <yuanm@andrew.cmu.edu>
 *          Yipeng Yun <yipengy@andrew.cmu.edu>
 * Date: 	Dec 11, 2011
 */

#include <asm.h>

.file "swi_asm.S"

@ Call the SWI dispatcher with the SWI number and return to user mode.
FUNC(swi_handler)
  STMFD sp!, {r0-r12, lr}   @ store gp registers
  MOV   r1, sp              @ pointer to parameters on stack
  MRS   r0, spsr            @ get SPSR into gp register
  STMFD sp, {r0, sp, lr}^
  SUB   sp, sp, #12

  MSR   CPSR_c, #0x53
   
  LDR   r2, =global_data    @ load saved register8 pointer
  LDR   r8, [r2]            @ restore r8
  LDR   r0, [lr, #-4]       @ extract the SWI number
  BIC   r0, r0, #0xFF000000 @ bit mask SWI number
  BL    swi_dispatch        @ branch to C handler

  MSR   CPSR_c, #0xD3

  LDMFD sp, {r0, sp, lr}^
  ADD   sp, sp, #12
  MSR   spsr, r0            @ restore SPSR from r2
  LDMFD sp!, {r0-r12, lr}   @ restore gp registers
  MOVS  pc, lr              @ return from handler to user mode
